#include <iostream>

#include "highgui.h"
#include "cv.h"

#include "camshifter/capture.h"
#include "motion.h"
#include "face/faceson.h"
#include "eigen/eigen.h"


#include "mythread.h"
#include <QMutex>


//to lock the thread
void MyThread::turn_me_off(){
    QMutex my_mutex;
    my_mutex.lock();
    runme = false;
    //printf("\nI released the objet\n");
    my_mutex.unlock();
    //printf("\nLock unlock finished\n");

}



void MyThread::run(){
    runme = true;

	if( !initAll() ) exitProgram(-1);
    
     bool first = true;    
     CvSize imgSize;
     IplImage* movingAverage=0;
     IplImage* difference=0;
     IplImage* temp=0;
     
     EigenTest *et=0;
	// Capture and display video frames until a face
	// is detected
    int isColor = 1;
    int fps     = 5;  // or 30
    int frameW ; // 744 for firewire cameras
    int frameH ; // 480 for firewire cameras
    CvVideoWriter *writer = 0;
    int i=0,m=1;
    char buffer[10];
    char temp_name[100];
	
    //the startSurveilance is controlled with butt
    while(runme)
	{

		// Look for a face in the next video frame
		captureVideoFrame();
        //update interface
        emit reloadFrameImage();
        //nah buraya motion tracker kocaz plazma gibi
        if(first){
    
            imgSize.width = pVideoFrameCopy->width;
            imgSize.height =pVideoFrameCopy->height;
            
            frameW=pVideoFrameCopy->width;
            frameH=pVideoFrameCopy->height;
          
            #ifdef unix
            remove_old_images();
            if (i<10)
                sprintf(temp_name,"outme/00%d.jpg",i);
            else if( i>=10 && i< 100)
                sprintf(temp_name,"outme/0%d.jpg",i);
                cvSaveImage(temp_name,pVideoFrameCopy);
            #endif
            
            writer = cvCreateVideoWriter("outme\\out.avi",CV_FOURCC('D','I','V','X'),fps,cvSize(frameW,frameH),isColor);
            movingAverage = cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
            difference=cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
            temp=cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
	      
            difference = cvCloneImage(pVideoFrameCopy);
            temp = cvCloneImage(pVideoFrameCopy);
            
            cvConvertScale(pVideoFrameCopy, movingAverage, 1.0, 0.0);
            first = false;


       }else{
         cvRunningAvg(pVideoFrameCopy, movingAverage, 0.020, NULL);
       }

        //cout << "Some stuff here "<<endl;
        if (motion(pVideoFrameCopy,movingAverage,difference,temp)){

            // bu cout elemanini plazmaya verecaz
            //cout << "Hareket\n"<<endl;
            emit sendMesageToMaster("Hareket olustu");
            cvSaveImage("lc.jpg",pVideoFrameCopy);
            
            //face detection from here
            //runface(pVideoFrameCopy);
            
            if(runface(pVideoFrameCopy)){
                //update screen
                emit reloadCropImage();
                
                if(!et)
                    et = new EigenTest();
                    
                    QString temp_eigen_result;
                    temp_eigen_result=et->recognize("tester","learn");
                    delete et;
                    et = 0;

             if(!temp_eigen_result.isEmpty()){

                // will be show on the pane
                QString person_found_mesage = "Veri tabaninda kisi bulundu,merhaba :";
                person_found_mesage.append(temp_eigen_result);
               
                emit sendMesageToMaster(person_found_mesage);
                emit sendDialogMessage(person_found_mesage);
                sleep(2); // not to start immediately !

                cout << "The user found in the database\n" << endl;
                cout << "Dont send the video clear all data" << endl;
                //buraya generic kod koymak lazim ama iste
                #ifdef unix
                remove_old_images();
                #endif

                //will save the video into recognized folder
                DbOperation *db = new DbOperation();
                db->moveFile("outme","recognized","out.avi","out.avi",0);
                delete db;
                db = 0;

                //framw kismini 0 yapalim tekrar devam etsin
                i=0; 
                //we dont break when found a face
                //cout << "Press a key to continue" << endl;
                //getchar();
             }
             else{
                //cout << "Not recognized person or object!\n"<<endl;
                emit sendMesageToMaster("Ekranda taninmayan obje veya kisi!");
             }  
            } 
            if(i<99){
                i++;
                #ifdef unix             
                //save image
                if (i<10)
                    sprintf(temp_name,"outme/00%d.jpg",i);
                    else if(i>=10 && i< 100)
                        sprintf(temp_name,"outme/0%d.jpg",i);
                        cvSaveImage(temp_name,pVideoFrameCopy);
                #endif
            
                cvWriteFrame(writer,pVideoFrameCopy);
                }
            else{
                #ifdef unix
                    //send the video ...
                    run_ffmeg();
                #endif
                    cvReleaseVideoWriter(&writer);
                    char name[100]="outme\\out";
                    sprintf(buffer,"%d",m);
                    strcat(name,buffer);
                    strcat(name,".avi");
                    m++;
                    i=0;
                    
                    writer = cvCreateVideoWriter(name,CV_FOURCC('D','I','V','X'),fps,cvSize(frameW,frameH),isColor);
                    
                    //move it to another folder to be send
                    DbOperation *db = new DbOperation();
                    db->moveFile("outme","notrecognized","out.avi","out.avi",0);
                    delete db;
                    db = 0;
                    emit sendMesageToMaster("Yabanci sahis cekildi ve videosu sunucuya gnnderiliyor ...");
                    emit sendDialogMessage("Yabanci sahis cekildi ve videosu sunucuya gnnderiliyor ...");
                    sleep(2);
                    //cout << "Moved file to be sent to the server" << endl;
                    //cout << "Press a key to continue "<<endl;
                    //getchar();
                    }

        }

    }

    // the eigen tester released
    if(et) {
        delete et;
        et = 0;
    }
  // cvReleaseVideoWriter(&writer);
    cvReleaseImage(&temp);
    cvReleaseImage(&difference);
    cvReleaseImage(&movingAverage);
	
	exitProgram(0);



    //exec();
}



//////////////////////////////////
// initAll()
//
int MyThread::initAll()
{

	if( !initCapture() ) return 0;
	// Startup message tells user how to begin and how to exit
	
    /**
    printf( "\n********************************************\n"
	        "To exit, click inside the video display,\n"
	        "then press the ESC key\n\n"
			"Press <ENTER> to begin"
			"\n********************************************\n" );
	fgetc(stdin);
    **/

	// Create the display window

	// Initialize tracker

	return 1;
}


//////////////////////////////////
// exitProgram()
//
void MyThread::exitProgram(int code)
{
	cvReleaseImage( &pVideoFrameCopy );

	// Release resources allocated in other project files
	closeCapture();
    pVideoFrameCopy = 0; // to reuse it !
    
    /**
    if(code==-1){
        QString cameraeror = "Check your camera some problem occured!";
        QMessageBox::information(this,"Kamera Error",cameraeror);

    }
    **/
    //exit(code);
}


//////////////////////////////////
// captureVideoFrame()
//
void MyThread::captureVideoFrame()
{
	// Capture the next frame
	IplImage  * pVideoFrame = nextVideoFrame();
	if( !pVideoFrame ) exitProgram(-1);

	// Copy it to the display image, inverting it if needed
	if( !pVideoFrameCopy )
		pVideoFrameCopy = cvCreateImage( cvGetSize(pVideoFrame), 8, 3 );
	cvCopy( pVideoFrame, pVideoFrameCopy, 0 );
	pVideoFrameCopy->origin = pVideoFrame->origin;

	if( 1 == pVideoFrameCopy->origin ) // 1 means the image is inverted
	{
		cvFlip( pVideoFrameCopy, 0, 0 );
		pVideoFrameCopy->origin = 0;
	}
	
}
#ifdef unix
void MyThread::run_ffmeg(){
    
    system("rm outme/*.avi");
    system("ffmpeg -r 5 -b 1800 -i outme/%03d.jpg -r 10 outme/out.avi");
    system("rm outme/*.jpg");
    //here will move file to client to send it
    cout << "System files runned successfully :)"<<endl;

}

void MyThread::remove_old_images(){

    system("rm outme/*.jpg");
}

#endif


